#ifndef Date_First
#define Date_First
#ifdef __GNUG__
#pragma interface
#endif

#include "Types.h"
#include "Stream.h"

//---- Date --------------------------------------------------------------------

class Date {
public:
	Date();
	Date(long sec, long msec= 0);
	Date(const Date &d);

	//----- access/conversion
	long Sec() const;
	long MSec() const;
	const char *AsString() const;
		
	//----- operators
	Date operator= (const Date &d);

	Date operator+= (const Date &d);
	Date operator-= (const Date &d);
	Date operator*= (const Date &d);
	Date operator/= (const Date &d);

	friend Date operator- (const Date &d);
	friend Date operator+ (const Date &d1, const Date &d2);
	friend Date operator- (const Date &d1, const Date &d2);
	friend Date operator* (const Date &d1, const Date &d2);
	friend Date operator/ (const Date &d1, const Date &d2);

	//----- comparison
	friend int Compare(const Date &d1, const Date &d2);

	//---- syntactic sugar: relational operators
	friend bool operator== (const Date &d1, const Date &d2);
	friend bool operator!= (const Date &d1, const Date &d2);
	friend bool operator< (const Date &d1, const Date &d2);
	friend bool operator<= (const Date &d1, const Date &d2);
	friend bool operator> (const Date &d1, const Date &d2);
	friend bool operator>= (const Date &d1, const Date &d2);
		
	//---- Stream operators
	friend OStream &operator<< (OStream &os, const Date &d);
	friend IStream &operator>> (IStream &is, Date &d);

private:
	long sec, msec;
};

inline Date::Date()
	{ sec= msec= 0; }
inline Date::Date(const Date &d)
	{ sec= d.sec; msec= d.msec; }
inline long Date::Sec() const
	{ return sec; }
inline long Date::MSec() const
	{ return msec; }
inline Date Date::operator= (const Date &d)
	{ sec= d.sec; msec= d.msec; return *this; }
inline Date Date::operator+= (const Date &d)
	{ return Date(sec+d.sec, msec+d.msec); }
inline Date Date::operator-= (const Date &d)
	{ return Date(sec-d.sec, msec-d.msec); }
inline Date Date::operator*= (const Date &d)
	{ return Date(sec*d.sec, msec*d.msec); }
inline Date Date::operator/= (const Date &d)
	{ return Date(sec/d.sec, msec/d.msec); }
inline Date operator- (const Date &d)
	{ return Date(-d.sec, -d.msec); }
inline Date operator+ (const Date &d1, const Date &d2)
	{ return Date(d1.sec+d2.sec, d1.msec+d2.msec); }
inline Date operator- (const Date &d1, const Date &d2)
	{ return Date(d1.sec-d2.sec, d1.msec-d2.msec); }
inline Date operator* (const Date &d1, const Date &d2)
	{ return Date(d1.sec*d2.sec, d1.msec*d2.msec); }
inline Date operator/ (const Date &d1, const Date &d2)
	{ return Date(d1.sec/d2.sec, d1.msec/d2.msec); }
inline bool operator== (const Date &d1, const Date &d2)
	{ return d1.sec == d2.sec && d1.msec == d2.msec; }
inline bool operator!= (const Date &d1, const Date &d2)
	{ return d1.sec != d2.sec || d1.msec != d2.msec; }
inline bool operator< (const Date &d1, const Date &d2)
	{ return d1.sec < d2.sec || (d1.sec == d2.sec && d1.msec < d2.msec); }
inline bool operator<= (const Date &d1, const Date &d2)
	{ return d1.sec < d2.sec || (d1.sec == d2.sec && d1.msec <= d2.msec); }
inline bool operator> (const Date &d1, const Date &d2)
	{ return d1.sec > d2.sec || (d1.sec == d2.sec && d1.msec > d2.msec); }
inline bool operator>= (const Date &d1, const Date &d2)
	{ return d1.sec > d2.sec || (d1.sec == d2.sec && d1.msec >= d2.msec); }

SimpleMetaDef(Date);

#endif
